import { ActionTree, Module, MutationTree } from 'vuex'
import { RouteRecordName, RouteRecordNormalized, RouteRecordRaw } from 'vue-router'
import { IRootState } from '@/store'

export interface RouteLocationWithFullPath extends RouteRecordNormalized {
  fullPath?: string;
}

export interface ITagsViewState {
  // 存放当前的 tagsView 集合
  visitedViews: RouteLocationWithFullPath[];
  // 根据 name 做路由缓存集合
  cachedViews: RouteRecordName[]
}

const mutations: MutationTree<ITagsViewState> = {
  // 添加可显示tags
  ADD_VISITED_VIEW(state, view) {
    if (state.visitedViews.some((v) => v.path === view.path)) return
    state.visitedViews.push(
      Object.assign({}, view, {
        title: view.meta.title || 'tag-name'
      })
    )
  },
  DEL_VISITED_VIEW(state, view) {
    const i = state.visitedViews.indexOf(view)
    if (i > -1) {
      state.visitedViews.splice(i, 1)
    }
  },
  ADD_CACHED_VIEW(state, view) {
    if (state.cachedViews.includes(view.name)) {
      return
    }
    if (!view.meta.noCache) {
      state.cachedViews.push(view.name)
    }
  },
  DEL_CACHED_VIEW(state, view) {
    const index = state.cachedViews.indexOf(view)
    index > -1 && state.cachedViews.splice(index, 1)
  },
  DEL_ALL_CACHED_VIEWS(state) {
    state.cachedViews = []
  },
  // 清空可显示列表
  DEL_ALL_VISITED_VIEWS(state) {
    // 对于affix为true的路由 tag view 是不能删除的
    state.visitedViews = state.visitedViews.filter(tag => tag.meta.affix)
  },
  // 删除标签导航其他可显示tag 除了 affix为true 以及当前右键选中的view
  DEL_OTHERS_VISITED_VIEWS(state, view: RouteRecordRaw) {
    state.visitedViews = state.visitedViews.filter(tag => tag.meta.affix || (tag.path === view.path))
  },
  // 删除缓存列表里其他tag 除了当前右键选中的view
  DEL_OTHERS_CACHED_VIEWS(state, view: RouteRecordRaw) {
    state.cachedViews = state.cachedViews.filter(name => name !== view.name)
  }
}

const actions: ActionTree<ITagsViewState, IRootState> = {
  // 添加tags view
  addView({ dispatch }, view: RouteRecordRaw) {
    dispatch('addVisitedView', view)
    dispatch('addCachedView', view)
  },
  // 添加可显示的 tags view
  addVisitedView({ commit }, view: RouteRecordRaw) {
    commit('ADD_VISITED_VIEW', view)
  },
  delVisitedView({ commit }, view: RouteRecordRaw) {
    commit('DEL_VISITED_VIEW', view)
  },
  // 删除指定 标签
  delView({ dispatch }, view: RouteRecordRaw) {
    return new Promise((resolve) => {
      // 删除显示的路由tag
      dispatch('delVisitedView', view)
      // 删除缓存的路由
      dispatch('delCachedView', view)
      resolve(null)
    })
  },
  // 添加可缓存标签
  addCachedView({ commit }, view: RouteRecordRaw) {
    commit('ADD_CACHED_VIEW', view)
  },
  // 从缓存中删除 tag view
  delCachedView({ commit }, view: RouteRecordRaw) {
    return new Promise(resolve => {
      commit('DEL_CACHED_VIEW', view)
      resolve(null)
    })
  },
  delAllCachedViews({ commit }) {
    commit('DEL_ALL_CACHED_VIEWS')
  },
  // 清空可显示列表
  delAllVisitedView({ commit }) {
    commit('DEL_ALL_VISITED_VIEWS')
  },
  // 清空可显示列表和可缓存列表
  delAllView({ dispatch }) {
    return new Promise(resolve => {
      dispatch('delAllCachedViews')
      dispatch('delAllVisitedView')
      resolve(null)
    })
  },
  // 关闭其他tag
  delOthersViews({ dispatch }, view: RouteRecordRaw) {
    dispatch('delOthersVisitedViews', view)
    dispatch('delOthersCachedViews', view)
  },
  // 关闭其他可显示tag
  delOthersVisitedViews({ commit }, view: RouteRecordRaw) {
    commit('DEL_OTHERS_VISITED_VIEWS', view)
  },
  // 关闭其他缓存tag
  delOthersCachedViews({ commit }, view: RouteRecordRaw) {
    commit('DEL_OTHERS_CACHED_VIEWS', view)
  }
}

const tagsView: Module<ITagsViewState, IRootState> = {
  namespaced: true,
  state: {
    visitedViews: [],
    cachedViews: []
  },
  mutations,
  actions
}

export default tagsView
